/**********************************
 * 文件:qt 下gsoap 服务器用
 * 创建者:林鸿铭
 * 创建时间:2016.11.28
 * copyright:(c)同川科技
 * 备注:有未确定数据类型,暂时"待定" 看门狗有待定
 *
 * 修改者:林鸿铭 2016.11.30
 **********************************/

#include "rosservergsoap.h"
//#include <qdebug.h>
//#include "gSoapFoundation/rosgsoapnamespaceStub.h"
using namespace rosgsoapnamespace;
#include <iostream>
#include "guiapi.h"

extern RosGuiApi *rosGuiApi;

//***********************************************************************
/**
 * @brief copyTask      获取实例化指针:供外部的gsoap接口使用
 */
RosServerGsoap *copyTask = NULL;

/**
 * @brief threadRun     线程:供gsoap服务器接收服务使用(更新用)
 */
void* threadRunUpdate(void *arg)
{
    std::cout<<"start the thread of Gsoap RecvLoop threadRunUpdate"<<std::endl;
    copyTask->gsoapServerUpdate->loopRecvServer();
}

//*******HmiGsoap*********************************************************
RosServerGsoap::RosServerGsoap()
{

    printf("RosServerGsoap\n");
    //提供组件类给外部使用
    copyTask = this;//获取指针  

    if(openServer())
    {

    }
}

RosServerGsoap::~RosServerGsoap()
{
    //退出清空
    gsoapServerUpdate->quitServer();      //清空服务器实例(更新用)
    pthread_cancel(tidUpdate);            //清除线程
    pthread_join(tidUpdate, NULL );
}



bool RosServerGsoap::openServer()
{
    //初始化gsoap服务器对象(更新用)
    gsoapServerUpdate = new GsoapServerForRos;
    if(!gsoapServerUpdate->startServer(ROS_GSOAP_PORT))
    {
        std::cout << "can not creat the RosServerGsoap::openServer" <<std::endl;
        return false;
    }

    //启动线程:循环接收客户端连接(更新用)
    int createResult = pthread_create(&tidUpdate,NULL,threadRunUpdate,NULL);
    if(createResult!=0)
    {
        std::cout << "can not creat the thread" <<std::endl;
        return false;
    }

    return true;
}


namespace rosgsoapnamespace {


//*******GSOAP接口函数部分******************************************************
//测试用
int testFoundation(soap *, rosgsoapnamespace::UserInfo userInfo, rosgsoapnamespace::UserInfo &returnnfo)
{
    std::cout <<userInfo.account<<std::endl;
    std::cout <<userInfo.ip<<std::endl;
    std::cout <<userInfo.operationSystem<<std::endl;
    std::cout <<userInfo.password<<std::endl;

    returnnfo.account = 99999;
    returnnfo.ip ="return ip is *******";

    if(userInfo.account == 0)
    {
        std::string testS;
        testS = "AB";//2
        testS = testS + testS;//4
        testS = testS + testS;//8
        testS = testS + testS;//16
        testS = testS + testS;//32
        testS = testS + testS;//64
        testS = testS + testS;//128
        testS = testS + testS;//256
        testS = testS + testS;//512
        testS = testS + testS;//1024 1m
        testS = testS + testS;//2m
        testS = testS + testS;//4m
        testS = testS + testS;//8m
        returnnfo.operationSystem = testS;
        returnnfo.password = "123456";
    }
    else
    {
        returnnfo.operationSystem = "ok";
        returnnfo.password = "123456*******";
    }

    return 0;//必须有
}



//***************AGV接口函数部分 hmi->agvBaseControl->ros********************************

//地图
int setMapSolver(soap *,rosgsoapnamespace::UserInfo userInfo,enum E_MAP_SOLVER solverIn,
                 int laserCount,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setMapSolver";
    std::cout << "setMapSolver" <<std::endl;
    rosGuiApi->setMapSolver(userInfo,solverIn,laserCount,returnFlag);

    return 0;//必须有
}

int createMapStart(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: createMapStart";
    rosGuiApi->createMapStart(userInfo,returnFlag);
    std::cout << "createMapStart" <<std::endl;
    return 0;//必须有
}
int createMapEnd(soap *,rosgsoapnamespace::UserInfo userInfo,std::string mapName,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: createMapEnd";
    std::cout << "createMapEnd" <<std::endl;
    rosGuiApi->createMapEnd(userInfo,mapName,returnFlag);

    return 0;//必须有
}
int loadMap(soap *,rosgsoapnamespace::UserInfo userInfo,std::string mapName,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: loadMap";
    std::cout << "loadMap" <<std::endl;
    rosGuiApi->loadMap(userInfo,mapName,returnFlag);

    return 0;//必须有
}
//添加虚拟墙
int addVitrualBlock(soap *,rosgsoapnamespace::UserInfo userInfo,std::string configFilePath,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: addVitrualBlock";
    std::cout << "addVitrualBlock" <<std::endl;

    return 0;//必须有
}

int deleteVitrualBlock(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: deleteVitrualBlock";

    return 0;//必须有
}

int addForbidenZone(soap *,rosgsoapnamespace::UserInfo userInfo,double x_start,double y_start
                    ,double x_end,double y_end,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: addForbidenZone";

    return 0;//必须有
}

//定位
int setOdomSolver(soap *,rosgsoapnamespace::UserInfo userInfo,enum E_ODOM_SOLVER solverIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setOdomSolver";
     rosGuiApi->setOdomSolver(userInfo,solverIn,returnFlag);
    return 0;//必须有
}
int setLocationSolver(soap *,rosgsoapnamespace::UserInfo userInfo,enum E_MAP_SOLVER solverIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setLocationSolver";
    E_LOCATION_SOLVER solverIn2=E_LOCATION_SOLVER_AMCL;
    rosGuiApi->setLocationSolver(userInfo,solverIn2,returnFlag);
    return 0;//必须有
}
int getVehiclePosition(soap *,rosgsoapnamespace::UserInfo userInfo,struct VehiclePosition& positionReturn)
{
    //qDebug()<<"Ros gsoap server: getVehiclePosition";
    rosGuiApi->getVehiclePosition(userInfo,positionReturn);
    return 0;//必须有
}
int setVehiclePosition(soap *,rosgsoapnamespace::UserInfo userInfo,struct VehiclePosition positionIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setVehiclePosition";
    rosGuiApi->setVehiclePosition(userInfo,positionIn,returnFlag);
    return 0;//必须有
}

//轨迹规划和行驶
int setReplanCoutLimitWhenFailure(soap *,rosgsoapnamespace::UserInfo userInfo,int countLimit,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setReplanCoutLimitWhenFailure";
     rosGuiApi->setReplanCoutLimitWhenFailure(userInfo,countLimit,returnFlag);
    return 0;//必须有
}
int setTrajectoryGlobalPlanSolver(soap *,rosgsoapnamespace::UserInfo userInfo,
                                  enum E_TRAJECTORY_GLOBAL_SOLVER solverIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setTrajectoryGlobalPlanSolver";
     rosGuiApi->setTrajectoryGlobalPlanSolver(userInfo,solverIn,returnFlag);
    return 0;//必须有
}
int setTrajectoryLocalPlanSolver(soap *,rosgsoapnamespace::UserInfo userInfo,enum E_TRAJECTORY_LOCAL_SOLVER solverIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setTrajectoryLocalPlanSolver";
    rosGuiApi->setTrajectoryLocalPlanSolver(userInfo,solverIn,returnFlag);
    return 0;//必须有
}
int moveToPosition(soap *,rosgsoapnamespace::UserInfo userInfo,struct VehiclePosition positionIn,
                   double velocity,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: moveToPosition";
     rosGuiApi->moveToPosition(userInfo,positionIn,velocity,returnFlag);
    return 0;//必须有
}
int moveFollowPath(soap *,rosgsoapnamespace::UserInfo userInfo,std::vector<struct VehiclePosition> pathIn,
                   double velocity,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: moveFollowPath";

    return 0;//必须有
}
int changeVelocity(soap *,rosgsoapnamespace::UserInfo userInfo,double velocity,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: changeVelocity";
     rosGuiApi->changeVelocity(userInfo,velocity,returnFlag);
    return 0;//必须有
}
int getMovingStatus(soap *,rosgsoapnamespace::UserInfo userInfo,enum E_GOAL_STATUS& status)
{
    //qDebug()<<"Ros gsoap server: getMovingStatus";
     rosGuiApi->getMovingStatus(userInfo,status);
    return 0;//必须有
}
int getRemainningTime(soap *,rosgsoapnamespace::UserInfo userInfo,double &timeOut)
{
    //qDebug()<<"Ros gsoap server: getRemainningTime";
    rosGuiApi->getRemainningTime(userInfo,timeOut);
    return 0;//必须有
}
int getRemainningDistance(soap *,rosgsoapnamespace::UserInfo userInfo,double &distanceOut)
{
    //qDebug()<<"Ros gsoap server: getRemainningDistance";
    rosGuiApi->getRemainningDistance(userInfo,distanceOut);
    return 0;//必须有
}
int ceaseMotion(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: ceaseMotion";
//    rosGuiApi->ceaseMotion(userInfo,returnFlag);
    return 0;//必须有
}
int startMotion(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: startMotion";
//    rosGuiApi->startMotion(userInfo,returnFlag);
    rosGuiApi->startNavigation(userInfo,returnFlag);
    return 0;//必须有
}
int cancelMotion(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: cancelMotion";
    rosGuiApi->cancelMotion(userInfo,returnFlag);
    return 0;//必须有
}

//设置
int setPositionArrivedAccuracy(soap *,rosgsoapnamespace::UserInfo userInfo,double accuracyIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setPositionArrivedAccuracy";
    rosGuiApi->setPositionArrivedAccuracy(userInfo,accuracyIn,accuracyIn,returnFlag);//HUALEI TODO
    return 0;//必须有
}
int setLocalPlanRange(soap *,rosgsoapnamespace::UserInfo userInfo,double rangeIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setLocalPlanRange";
    rosGuiApi->setLocalPlanRange(userInfo,rangeIn,rangeIn,returnFlag);
    return 0;//必须有
}
int setVehicleBorderOffset(soap *,rosgsoapnamespace::UserInfo userInfo,std::vector<double> point_x,
                           std::vector<double> point_y,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setVehicleBorderOffset";
    rosGuiApi->setVehicleBorder(userInfo,point_x,point_y,returnFlag);
    return 0;//必须有
}
int setGlobalBarrierOffset(soap *,rosgsoapnamespace::UserInfo userInfo,double offsetIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setGlobalBarrierOffset";
    rosGuiApi->setGlobalBarrierOffset(userInfo,offsetIn,returnFlag);
    return 0;//必须有
}
int setLocalBarrierOffset(soap *,rosgsoapnamespace::UserInfo userInfo,double offsetIn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setLocalBarrierOffset";
    rosGuiApi->setLocalBarrierOffset(userInfo,offsetIn,returnFlag);
    return 0;//必须有
}
int resetRosAll(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: resetRosAll";
//    rosGuiApi->resetRosAll(userInfo,returnFlag);
    return 0;//必须有
}

//状态
int getRosPackageStatus(soap *,rosgsoapnamespace::UserInfo userInfo,enum E_ROS_PACKAGE package,
                        enum E_ROS_PACKAGE_STATUS &status)
{
    //qDebug()<<"Ros gsoap server: getRosPackageStatus";
//    rosGuiApi->getRosPackageStatus(userInfo,package,status);
    return 0;//必须有
}

//IMU校准
int startImuCalibrate(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: startImuCalibrate";

    return 0;//必须有
}
int stopImuCalibrate(soap *,rosgsoapnamespace::UserInfo userInfo,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: stopImuCalibrate";

    return 0;//必须有
}

//信息传递
int getMessage(soap *,rosgsoapnamespace::UserInfo userInfo,std::vector<struct Message> &messageListReturn)
{
    //qDebug()<<"Ros gsoap server: getMessage";

    return 0;//必须有
}

int setWheelOdometerData(soap *,rosgsoapnamespace::UserInfo userInfo,int robotIdIn,struct OdemeterData odemeterDataReturn,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setWheelOdometerData";
    std::cout << "Ros gsoap server:setWheelOdometerData" <<std::endl;
    rosGuiApi->setWheelOdometerData(userInfo,robotIdIn,odemeterDataReturn,returnFlag);
    return 0;//必须有
}

int getVehicleVelocityComand(soap *,rosgsoapnamespace::UserInfo userInfo,int robotIdIn,
                             struct  VehicleVelocity &velocityComamnd)
{
    //qDebug()<<"Ros gsoap server: getVehicleVelocityComand";
//    std::cout << "Ros gsoap server:getVehicleVelocityComand" <<std::endl;
    rosGuiApi->getVehicleVelocityComand(userInfo,robotIdIn,velocityComamnd);
    std::cout << "velocityComamnd x:" <<velocityComamnd.x_move
              <<" y:"<<velocityComamnd.y_move<<" rotate:"<<velocityComamnd.z_rotate<<std::endl;
    return 0;//必须有
}

int setWheelMoveSpeed(soap *,rosgsoapnamespace::UserInfo userInfo,int robotIdIn, std::vector<double>wheelMoveSpeed,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setWheelMoveSpeed";

    return 0;//必须有
}

int setWheelPathLength(soap *,rosgsoapnamespace::UserInfo userInfo,int robotIdIn, std::vector<double>wheelPathLength,int &returnFlag)
{
    //qDebug()<<"Ros gsoap server: setWheelPathLength";

    return 0;//必须有
}


}



